// 测试账号配置
const TEST_USERS = {
  valid: {
    username: 'user',
    password: '111111',
    nickname: '测试用户'
  }
}

describe('用户认证测试', () => {
  beforeEach(() => {
    // 在每个测试用例前访问登录页面
    cy.visit('/user/login')
    // 等待页面加载完成
    cy.get('.login-box').should('be.visible')
    // 清除 localStorage，确保每次测试都是全新状态
    cy.window().then((win) => {
      win.localStorage.clear()
    })
  })

  // 在所有测试开始前清理遗留的测试数据
  before(() => {
    cy.task('db:clean', 'test%')
  })

  // 在所有测试结束后清理数据库并验证
  after(() => {
    // 清理所有以 test 开头的测试用户
    cy.task('db:clean', 'test%')
    // 验证清理是否成功
    cy.task('db:verify', 'test%').then((count) => {
      expect(count).to.equal(0)
    })
  })

  describe('登录功能', () => {
    it('流程1：登录表单显示测试', () => {
      // 验证登录表单的关键元素是否存在
      cy.get('.login-header h2').should('contain', '书籍分享平台-用户')
      cy.get('.tab-item').first().should('have.class', 'active')
      cy.get('.el-input input[placeholder="用户名"]').should('exist').and('be.visible')
      cy.get('.el-input input[placeholder="密码"]').should('exist').and('be.visible')
      cy.get('.el-checkbox').should('contain', '记住我').and('be.visible')
      cy.get('.submit-btn').should('exist').and('be.visible').and('not.be.disabled')
      cy.get('.skip-login').should('exist').and('be.visible')
    })

    it('流程2：空字段验证测试', () => {
      // 点击提交按钮前确保表单为空
      cy.get('.el-input input[placeholder="用户名"]').should('have.value', '')
      cy.get('.el-input input[placeholder="密码"]').should('have.value', '')
      cy.get('.submit-btn').click()
      // 等待验证消息出现
      cy.get('.el-form-item__error').should('be.visible')
      cy.get('.el-form-item__error').should('have.length.at.least', 1)
    })

    it('流程3：用户名格式验证测试', () => {
      cy.get('.el-input input[placeholder="用户名"]').type('ab')
      cy.get('.el-input input[placeholder="密码"]').click() // 触发验证
      // 等待验证消息出现
      cy.get('.el-form-item__error')
        .should('be.visible')
        .and('contain', '用户名只能包含3-10位字母或数字')
    })

    it('流程4：密码格式验证测试', () => {
      cy.get('.el-input input[placeholder="密码"]').type('123')
      cy.get('.el-input input[placeholder="用户名"]').click() // 触发验证
      // 等待验证消息出现
      cy.get('.el-form-item__error')
        .should('be.visible')
        .and('contain', '密码只能包含6-10位字母或数字')
    })

    it('流程5：错误凭据登录测试', () => {
      const wrongUser = {
        username: 'wronguser123',
        password: 'wrongpass123'
      }
      
      cy.get('.el-input input[placeholder="用户名"]').type(wrongUser.username)
      cy.get('.el-input input[placeholder="密码"]').type(wrongUser.password)
      cy.get('.submit-btn').click()
      
      // 使用 contains 而不是类选择器来查找错误消息
      cy.contains('用户名或密码错误').should('be.visible')
    })

    it('流程6：成功登录测试', () => {
      cy.get('.el-input input[placeholder="用户名"]').type(TEST_USERS.valid.username)
      cy.get('.el-input input[placeholder="密码"]').type(TEST_USERS.valid.password)
      cy.get('.el-checkbox').click() // 测试"记住我"功能
      cy.get('.submit-btn').click()
      
      // 添加超时时间，等待跳转
      cy.url().should('include', '/user/home', { timeout: 10000 })
      
      // 验证本地存储中的用户信息
      cy.window().then((win) => {
        expect(win.localStorage.getItem('token')).to.exist
      })
    })

    it('流程7：跳过登录功能测试', () => {
      cy.get('.skip-login .el-button').click()
      cy.url().should('include', '/user/home', { timeout: 10000 })
      // 验证是游客模式
      cy.window().then((win) => {
        expect(win.localStorage.getItem('token')).to.be.null
      })
    })
  })

  describe('注册功能', () => {
    beforeEach(() => {
      // 切换到注册标签
      cy.get('.tab-item').eq(1).click()
      // 等待注册表单显示
      cy.get('.register-form').should('be.visible')
    })

    it('流程8：注册表单显示测试', () => {
      cy.get('.tab-item').eq(1).should('have.class', 'active')
      cy.get('.el-input input[placeholder*="用户名"]').should('exist').and('be.visible')
      cy.get('.el-input input[placeholder*="昵称"]').should('exist').and('be.visible')
      cy.get('.el-input input[placeholder*="密码"]').should('exist').and('be.visible')
      cy.get('.el-input input[placeholder="确认密码"]').should('exist').and('be.visible')
      cy.get('.submit-btn').should('exist').and('be.visible').and('not.be.disabled')
    })

    it('流程9：空字段验证测试', () => {
      // 确保所有字段为空
      cy.get('.el-input input[placeholder*="用户名"]').should('have.value', '')
      cy.get('.el-input input[placeholder*="昵称"]').should('have.value', '')
      cy.get('.el-input input[placeholder*="密码"]').first().should('have.value', '')
      cy.get('.el-input input[placeholder="确认密码"]').should('have.value', '')
      
      cy.get('.submit-btn').click()
      cy.get('.el-form-item__error').should('be.visible')
      cy.get('.el-form-item__error').should('have.length', 4) // 四个必填字段
    })

    it('流程10：用户名格式验证测试', () => {
      cy.get('.el-input input[placeholder*="用户名"]').type('ab')
      cy.get('.el-input input[placeholder*="昵称"]').click() // 触发验证
      cy.get('.el-form-item__error')
        .should('be.visible')
        .and('contain', '用户名只能包含3-10位字母或数字')
    })

    it('流程11：昵称格式验证测试', () => {
      cy.get('.el-input input[placeholder*="昵称"]').type('a')
      cy.get('.el-input input[placeholder*="用户名"]').click() // 触发验证
      cy.get('.el-form-item__error')
        .should('be.visible')
        .and('contain', '昵称长度在2到6个字符之间')
    })

    it('流程12：密码不匹配验证测试', () => {
      cy.get('.el-input input[placeholder*="密码"]').first().type('password123')
      cy.get('.el-input input[placeholder="确认密码"]').type('password456')
      cy.get('.el-input input[placeholder*="用户名"]').click() // 触发验证
      cy.get('.el-form-item__error')
        .should('be.visible')
        .and('contain', '两次输入的密码不一致')
    })

    it('流程13：用户名已存在测试', () => {
      // 使用已存在的用户名尝试注册
      cy.get('.el-input input[placeholder*="用户名"]').type(TEST_USERS.valid.username)
      cy.get('.el-input input[placeholder*="昵称"]').type('新用户')
      cy.get('.el-input input[placeholder*="密码"]').first().type('111111')
      cy.get('.el-input input[placeholder="确认密码"]').type('111111')
      cy.get('.submit-btn').click()
      
      cy.contains('用户名已存在').should('be.visible')
    })

    it('流程14：完整注册并登录流程测试', () => {
      // 生成一个符合验证规则的用户名（3-10位字母或数字）
      const randomNum = Math.floor(Math.random() * 900) + 100 // 生成100-999的三位随机数
      const newUser = {
        username: `test${randomNum}`, // 例如：test123，总共7位
        nickname: '测试用户',         // 符合2-6个字符的要求
        password: '123456abc'         // 符合6-10位字母或数字的要求
      }
      
      // 测试前先清理可能存在的同名用户
      cy.task('db:clean', newUser.username)
      
      // 切换到注册标签
      cy.get('.tab-item').eq(1).click()
      cy.get('.register-form').should('be.visible')
      
      // 填写注册表单
      cy.get('.el-input input[placeholder*="用户名"]').type(newUser.username)
      cy.get('.el-input input[placeholder*="昵称"]').type(newUser.nickname)
      cy.get('.el-input input[placeholder*="密码"]').first().type(newUser.password)
      cy.get('.el-input input[placeholder="确认密码"]').type(newUser.password)
      cy.get('.submit-btn').click()
      
      // 验证注册成功
      cy.contains('注册成功', { timeout: 10000 }).should('be.visible')
      
      // 等待切换到登录表单，用户名应该自动填充，但需要手动输入密码
      cy.get('.tab-item').first().should('have.class', 'active')
      
      // 验证用户名已自动填充
      cy.get('.el-input input[placeholder="用户名"]').should('have.value', newUser.username)
      
      // 输入密码
      cy.get('.el-input input[placeholder="密码"]').type(newUser.password)
      
      // 点击登录按钮
      cy.get('.submit-btn').click()
      
      // 验证登录成功
      cy.url().should('include', '/user/home', { timeout: 10000 })
      
      // 验证本地存储中的用户信息
      cy.window().then((win) => {
        const token = win.localStorage.getItem('token')
        expect(token).to.exist
        // 验证token格式
        expect(token).to.match(/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/)
      })

      // 验证用户信息
      cy.request({
        method: 'GET',
        url: '/api/user/current',
        headers: {
          Authorization: `Bearer ${localStorage.getItem('token')}`
        }
      }).then((response) => {
        expect(response.status).to.eq(200)
        expect(response.body.data.username).to.eq(newUser.username)
        expect(response.body.data.nickname).to.eq(newUser.nickname)
      })

      // 测试完成后清理创建的测试用户并验证
      cy.task('db:clean', newUser.username)
      cy.task('db:verify', newUser.username).then((count) => {
        expect(count).to.equal(0)
      })
    })
  })
}) 